package com.limit.currentlimiting.aop;

import com.google.common.util.concurrent.RateLimiter;
import com.limit.currentlimiting.annotation.Limit;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

@Aspect
@Component
public class LimitAop {
    // 定义为一个组件注入Spring框架

    // guava提供的限流方法

    private ConcurrentHashMap<String, RateLimiter> rateLimiterConcurrentHashMap = new ConcurrentHashMap<>();

    @Around(value = "@annotation(com.limit.currentlimiting.annotation.Limit)")
    public Object around(ProceedingJoinPoint joinPoint) {

        // 获取拦截的方法名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Limit limit = signature.getMethod().getDeclaredAnnotation(Limit.class);

        double token = limit.token();
        String name = limit.name();

        RateLimiter rateLimiter = rateLimiterConcurrentHashMap.get(name);

        if (rateLimiter == null) {
            rateLimiter = RateLimiter.create(token);
            rateLimiterConcurrentHashMap.put(name, rateLimiter);
        }
        boolean result = rateLimiter.tryAcquire((int) token);

        if (!result) {
            return "当前访问人数过多，请稍后重试~";
        }

        try {
            return joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return "环绕通知";
    }
}
